package com.itzhanshen.auth.aop;

import com.itzhanshen.auth.entity.IntergrationAuthenticationEntity;
import com.itzhanshen.auth.entity.NcOauthTokenDTO;
import com.itzhanshen.auth.entity.RequestParamsThreadLocal;
import com.itzhanshen.auth.entity.UserHolder;
import com.nineclock.common.entity.Result;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NCException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

// 切面类
@Aspect
@Component
@Slf4j
public class AuthTokenAspect {
    //private static final String AUTH_TYPE = null;
    @Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Result result = null;
        Object obj = null;
        // 获取请求参数
        try {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
            log.info("Aop拦截到了密码认证");
            // 组装参数
            String authType = request.getParameter("auth_type");
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (parameterMap == null && authType == null) {
                throw new NCException(ResponseEnum.MESSAGE_PARAMS_LOST);
            }
            IntergrationAuthenticationEntity entity = new IntergrationAuthenticationEntity();
            entity.setAuthType(authType);
            entity.setAuthParameters(parameterMap);
            // 添加到ThreadLocal中 让后期差参数的进行取出获取
            RequestParamsThreadLocal.set(entity);
            // 放行,执行原始方法
          obj = joinPoint.proceed();
            /*=================后置增强===============*/
            //获取到原始方法执行的结果之后, 对其进行封装, 封装为项目中的统一结果Result类型
            if (obj != null) {
                ResponseEntity<OAuth2AccessToken> responseEntity = (ResponseEntity<OAuth2AccessToken>) obj;
                OAuth2AccessToken oAuth2AccessToken = responseEntity.getBody();
                // 判断状态码是否为成功
                if (responseEntity.getStatusCode().is2xxSuccessful()) {
                    // 封装数据
                    UserInfo userInfo = UserHolder.get();
                    result =  Result.success(new NcOauthTokenDTO(oAuth2AccessToken, userInfo));
                } else {
                    log.error("error:{}", responseEntity.getStatusCode().toString());
                   result = Result.errorCodeMessage(401, "获取令牌失败");
                }
            }

       /* } catch (Throwable throwable) {
            log.error(throwable.getMessage());*/
        } finally {
            // 删除该资源
            RequestParamsThreadLocal.remove();
        }
        return ResponseEntity.ok(result);
    }
}
